#ifndef __DJI_H
#define __DJI_H
#include "can_common.h"
#include "offline.h"
#include "rttypes.h"
#ifdef __cplusplus
extern "C"{
#endif


#include "motor_def.h"
#define MAX_DJI_MOTOR_NUMBER 12

/* 滤波系数设置为1的时候即关闭滤波 */
#define SPEED_SMOOTH_COEF 0.9f      // 最好大于0.85
#define CURRENT_SMOOTH_COEF 0.9f     // 必须大于0.9
#define ECD_ANGLE_COEF_DJI 0.043945f // (360/8192),将编码器值转化为角度制
#define DJI_TIMEOUT_TICKS 1000

/* DJI电机CAN反馈信息*/
typedef struct
{
    rt_uint16_t last_ecd;        // 上一次读取的编码器值
    rt_uint16_t ecd;             // 0-8191,刻度总共有8192格
    float angle_single_round; // 单圈角度
    float speed_rpm;          // 转速
    float speed_aps;          // 角速度,单位为:度/秒
    rt_int16_t real_current;     // 实际电流
    rt_uint8_t temperature;      // 温度 Celsius

    float total_angle;   // 总角度,注意方向
    rt_int32_t total_round; // 总圈数,注意方向
    float total_output_round; //输出轴总圈数
} DJI_Motor_Measure_s;

/**
 * @brief DJI intelligent motor typedef
 *
 */
typedef struct
{
    DJI_Motor_Measure_s measure;            // 电机测量值
    Motor_Control_Setting_s motor_settings; // 电机设置
    Motor_Controller_s motor_controller;    // 电机控制器
    // 分组发送设置
    uint8_t sender_group;
    uint8_t message_num;
    Motor_Type_e motor_type;        // 电机类型
    Motor_Working_Type_e stop_flag; // 启停标志
    CanMessage_Init_s CanMessage_Init;
    offline_manage_obj offline_manage_dji;
    rt_slist_t list;                   // 单链表节点

} DJIMotor_t;


DJIMotor_t *DJIMotorInit(Motor_Init_Config_s *config);

/**
 * @brief 被application层的应用调用,给电机设定参考值.
 *        对于应用,可以将电机视为传递函数为1的设备,不需要关心底层的闭环
 *
 * @param motor 要设置的电机
 * @param ref 设定参考值
 */
void DJIMotorSetRef(DJIMotor_t *motor, float ref);

/**
 * @brief 切换反馈的目标来源,如将角速度和角度的来源换为IMU(小陀螺模式常用)
 *
 * @param motor 要切换反馈数据来源的电机
 * @param loop  要切换反馈数据来源的控制闭环
 * @param type  目标反馈模式
 */
void DJIMotorChangeFeed(DJIMotor_t *motor, Closeloop_Type_e loop, Feedback_Source_e type);

/**
 * @brief 该函数被motor_task调用运行在rtos上,motor_stask内通过osDelay()确定控制频率
 */
void DJIMotorControl();

/**
 * @brief 停止电机,注意不是将设定值设为零,而是直接给电机发送的电流值置零
 *
 */
void DJIMotorStop(DJIMotor_t *motor);

/**
 * @brief 启动电机,此时电机会响应设定值
 *        初始化时不需要此函数,因为stop_flag的默认值为0
 *
 */
void DJIMotorEnable(DJIMotor_t *motor);

/**
 * @brief 修改电机闭环目标(外层闭环)
 *
 * @param motor  要修改的电机实例指针
 * @param outer_loop 外层闭环类型
 */
void DJIMotorOuterLoop(DJIMotor_t *motor, Closeloop_Type_e outer_loop);


void DecodeDJIMotor(struct rt_can_msg can_msg);



#ifdef __cplusplus
}
#endif

#endif // DJI_H